package com.pignest.hotel.service;

import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.apache.commons.lang.StringUtils;

import com.pignest.framework.util.Utils;
import com.pignest.hotel.beans.Booking;
import com.pignest.hotel.beans.BookingRoom;
import com.pignest.hotel.beans.Card;
import com.pignest.hotel.beans.Living;
import com.pignest.hotel.beans.LivingCustom;
import com.pignest.hotel.beans.LivingSpecifics;
import com.pignest.hotel.beans.Member;
import com.pignest.hotel.beans.Memberchargehistrory;
import com.pignest.hotel.beans.Room;
import com.pignest.hotel.beans.TbAccounts;
import com.pignest.hotel.beans.TbCloseAccounts;
import com.pignest.hotel.beans.TbGoods;
import com.pignest.hotel.beans.TbLiveGoodsBorrow;
import com.pignest.hotel.dao.BookingDao;
import com.pignest.hotel.dao.InComeDao;
import com.pignest.hotel.dao.LivingDao;
import com.pignest.hotel.definition.BookingStatus;
import com.pignest.hotel.definition.ChargeOpType;
import com.pignest.hotel.definition.InComeItemType;
import com.pignest.hotel.definition.LivingState;
import com.pignest.hotel.definition.OperateState;
import com.pignest.hotel.definition.PayMethod;
import com.pignest.hotel.definition.RoomLiveStatus;
import com.pignest.hotel.definition.RoomRepairStatus;
import com.pignest.hotel.definition.RoomUseStatus;
import com.pignest.hotel.spring.Services;
import com.pignest.hotel.system.Config;
import com.pignest.hotel.system.Hotel;
import com.pignest.hotel.system.InComeUtil;
import com.pignest.hotel.system.L;
import com.pignest.hotel.system.Logic;
import com.pignest.hotel.util.DateUtil;
import com.pignest.hotel.util.UIUtils;

/**
 * 接待 预订, 入住, 退房相关
 */
public class ReceptionService extends BaseService {

	private RoomService roomService;
	private BookingDao bookingDao;
	private LivingDao livingDao;
	private InComeDao incomeDao;
	

	/** 预订 */
	public void addBooking(Booking booking, List<String> roomIds) {
		booking.setReserved(roomIds == null ? 0 : roomIds.size());
		bookingDao.insert(booking);
		if (roomIds == null || roomIds.isEmpty()) {
			return;
		}
		for (String roomId : roomIds) {
			BookingRoom bb = new BookingRoom();
			bb.setBooking(booking);
			Room room = roomService.getRoom(roomId);
			bb.setRoom(room);
//			bb.setRoomType(room.getType());
			bb.setStatus(BookingStatus.ONGOING.name());
			bookingDao.insert(bb);
		}
	}
	public void modBooking(Booking booking,Room [] rooms ,boolean isChangeRoom,boolean isSetRoom)
	{
		bookingDao.update(booking);
		if(isSetRoom)//如果 要排房
		{
			if(isChangeRoom)
			{
				//先删除原来的预定排房
				if(booking.getBookingRooms()!=null)
				{
					for(BookingRoom bookingRoom : booking.getBookingRooms())
					{
						//deleted object would be re-saved by cascade 因为在Booking.hbm.xml 中cascade="all" 出现的
						bookingDao.delete(BookingRoom.class, bookingRoom.getId());
					}
				}
				//再更新现在选定的排房
				for(Room room:rooms)
				{
					BookingRoom bookingRoom = new BookingRoom();
					bookingRoom.setBooking(booking);
					bookingRoom.setRoom(room);
					bookingRoom.setRoomType(room.getType());
					bookingDao.insert(bookingRoom);
				}
			}
		}else
		{
			if(booking.getBookingRooms()!=null)
			{
				for(BookingRoom bookingRoom : booking.getBookingRooms())
				{
					bookingDao.delete(BookingRoom.class, bookingRoom.getId());
				}
			}
		}
	}
	
	/**
	 * 过滤某时间之前的, 某状态的预订(自动更新预订状态)
	 * @param status 预订状态, 非空
	 * @param time 时间, 非空
	 * */
	public List<Booking> listBookings(BookingStatus status) {
		return query(Booking.class, "status=?", new Object[] {status.name()}, null);
	}
	
	public List<Booking> listAllBookings() {
		return bookingDao.listAll(Booking.class);
	}

	public List<Booking> queryBooking(String name, String phone,
			BookingStatus status) {
		return bookingDao.query(name, phone, status);
	}

	public List<Booking> queryBooking(Date startTime, Date endTime) {
		return bookingDao.query(startTime, endTime);
	}
	
	/** 房间的当前入住 */
	public Living getLiving(Room room) {
		return livingDao.getLivingByRoom(room);
	}
	
	/** 房间的最近有效的预订 */
	public Booking getBooking(Room room) {
		return bookingDao.getBookingByRoom(room);
	}
	
	public List<Living> getLivingList(Room room){
		return livingDao.getLivingListByRoom(room);
	}
	
	///////////////////////////////////////////////////////////////////////////

	public void setBookingDao(BookingDao bookingDao) {
		this.bookingDao = bookingDao;
	}
	
	public void setLivingDao(LivingDao livingDao) {
		this.livingDao = livingDao;
	}
	
	public void setRoomService(RoomService roomService) {
		this.roomService = roomService;
	}

	public void setIncomeDao(InComeDao incomeDao) {
		this.incomeDao = incomeDao;
	}
	/**
	 * 加收房费
	 * @param Living 入住记录
	 * @param TbAccounts 入住项目
	 * @author zhugb
	 * 说明 ：新增入住项目->更新入住记录的使用及余额情况
	 * ***/
	public void addDayPay(final Living l,final TbAccounts ts){
		try{
			this.executeInTransaction(new Runnable(){
				@Override
				public void run() {
					insert(ts);
					InComeUtil.updateLiving(l.getId());
				}
			});

		}catch(Exception e){
			e.printStackTrace();

		}
	}
	/****
     * 计算消费情况
     */
    public Living updateCalculate(Living l){
    	//int balance=this.livingDao.queryConsumption(l.getId());
    	int balance =this.incomeDao.countAllConsums(l, false, true);
		//balanceTextbox.setValue(MoneyUtil.toString(balance));
    	int storage =l.getStorage();
    	l.setUsed(storage-balance);
    	l.setAvailable(balance);
    	this.update(l);
        return l;
    }
   
	/**
	 * 为入住的增加消费项目
	 * @param Living l 入住记录
	 * @param 
	 * @author zhugb
	 * **/
	public void insertProjects(TbAccounts ts,TbGoods goods){

		this.insert(ts);
		if(goods!=null)
		this.update(goods);
	}
	/**
	 * 增加多条消费项目涉及到事务
	 * ***/
	public String insertProjects(String[] ids, Living living, String payReason) {

		String re = "";
		for (int i = 0; i < ids.length; i++) {
			String id = (String) ids[i];
			TbLiveGoodsBorrow gb = this.get(TbLiveGoodsBorrow.class, id);
			if (gb.getBacktime() != null)
				return "所选择的物品有已归还了，";
			gb.setBacktime(new Date());
			TbAccounts ac = new TbAccounts();
			ac.setLiving(living);
			ac.setType(InComeItemType.PCF.name());
			ac.setCounts(gb.getCount());
			ac.setName(gb.getTbGoods().getName());
			int p1 = gb.getTbGoods().getPrice();// 消费单价
			int p = p1 * gb.getCount();
			ac.setPrice(-p);
			ac.setOpdate(DateUtil.currentDateToString(DateUtil.DEFAULT_DATE_FORMAT));
			ac.setEndstate("否");
			ac.setOptime(new Date());
			ac.setPrice2(p1);
			ac.setRemark(payReason + ":物品消费");

			// 剩余数量
			TbGoods gd = null;
			if (gb.getTbGoods() != null) {
				gd = gb.getTbGoods();
				Integer c = gd.getCount();
				if (c != null) {
					int c1 = c - gb.getCount();
					gd.setCount(c1);
					this.update(gb);
				}
			}
			this.insertProjects(ac, gd);
			InComeUtil.updateLiving(living.getId());
		}
		return re;

	}
	/**
	 * 删除消费项目
	 * @author zhugb
	 * @param  项目ID
	 * 还未加入权限控制如只能值班经理才能删除，或者权限更高的人才能控制
	 * 
	 * */
	public void deleteProjects(String []ids,Living l){
		if(ids==null)
			return ;
		for(int i=0;i<ids.length;i++){
			//this.delete(TbAccounts.class, ids[i]);
			TbAccounts ac =this.get(TbAccounts.class, ids[i]);
			ac.setState(TbAccounts.STATE_DELETE);
			ac.setOptime(new Date());
			ac.setOpUser(Hotel.getCurrentUser().getName());
			this.update(ac);
			L.log(L.Action.INSERT, "account", ac.toSimpleString());
		}
	}
	

	public List<TbGoods> queryGoodslistAll(){
		StringBuffer hql=new StringBuffer();
		hql.append(" from TbGoods ");
		return this.find(hql.toString());
	}
	/***
	 * 设置物品归还时间
	 * 系统判断是否归还是以是否有归还时间来判定的
	 * @author zhugb
	 * @param ids[] id组 
	 * ***/
    public void updateBorrowGoodsBackTime(String []ids){
    	if(ids==null)
    		return ;
    	for(int i=0;i<ids.length;i++){
    		String id=ids[i];
    		TbLiveGoodsBorrow gb= this.get(TbLiveGoodsBorrow.class, id);
    		gb.setBacktime(new Date());
    		this.update(gb);
    	}
    }
    /**
     * 是否归还物品
     * 
     * ***/
    public boolean isGoodsBack(Living l){
    	if(l!=null){
    		StringBuffer hql=new StringBuffer();
    		 hql.append(" from TbLiveGoodsBorrow b where b.living.id='"+l.getId()+"' and backtime is null");
    		 List <TbLiveGoodsBorrow> goodsBorrowList=this.find(hql.toString());
    		 if(goodsBorrowList!=null&&goodsBorrowList.size()>0){
    			 return true;
    		 }else{
    			return false;
    		 }
    	}else
    		return false;
    }
    /**
     * 是否已结账
     * ***/
    public boolean isCheckOut(Living l){
    	if(l!=null){
    		StringBuffer hql=new StringBuffer();
    		 hql.append(" from TbCloseAccounts b where b.living.id='"+l.getId()+"'");
    		 List <TbCloseAccounts> colseAcList=this.find(hql.toString());
    		 if(colseAcList!=null&&colseAcList.size()==1){
    			 return true;
    		 }else{
    			return false;
    		 }
    	}else
    		return false;
    }
    
    public List<TbAccounts> listRecentAccounts(Member m) {
    	return query(TbAccounts.class, "o.living.member=? and o.state='"+TbAccounts.STATE_NORMAL+"' order by opdate desc", 15, 0, new Object[] {m}, null);
    }
    @Deprecated
    public boolean updateCheckOut(Living l,TbAccounts ts,TbCloseAccounts ca,Room room,Memberchargehistrory mch,Card card){
    	try{
    		this.update(l);
    		if(ts!=null)
    			this.insert(ts);
    		updateCheckOutAccount(l);
    		this.insert(ca);
    		room.setLiveStatus(RoomLiveStatus.EMPTY.name());
    		room.setUseStatus(RoomUseStatus.DIRTY.name());
    		this.update(room);
    		
    		if(mch!=null)
    		{
    	    	this.insert(mch);
    	    	Member m =l.getMember();
    	    	int b =Services.getMemberService().queryMemberBalance(m);
    	    	m.setBalance(b);
    	    	this.update(m);
    		}else
    		{   Member m =l.getMember();
    			if(m!=null){
    				int b =Services.getMemberService().queryMemberBalance(m);
        	    	m.setBalance(b);
        	    	this.update(m);
    			}
    		}
    		if(card!=null)
    			this.update(card);
    			
    		return true;
    	}catch(Exception e){
    		e.printStackTrace();
    		return false;
    	}
    }
    /**全部结账
     * @param l living一条入住住记录
     * @param TbCloseAccounts ca 结算账务
     * @param TbAccounts ac 加收账单 为空则不加收
     * @param Memberchargehistrory mch 会员消费 为空则不是会员消费
     * */
    @Deprecated
    public void allCheck(Living l,TbCloseAccounts ca,TbAccounts ac,Memberchargehistrory mch,int pay)
    {
    	//加收
    	if(ac!=null){
    		this.insert(ac);
    	}
    	//账单入库
    	if(ca!=null)
    		this.insert(ca);
    	if(mch!=null){
    		this.insert(mch);
    		//更新会员总账
    		Member m=mch.getMember();
    		int b =Services.getMemberService().queryMemberBalance(m);
	    	m.setBalance(b);
	    	this.update(m);
    	}
    	//查找当前入住的所有未结账单
    	List<TbAccounts> acc =this.queryAccountsList(l);
    	//更新账单
    	 for(TbAccounts a:acc){
         	a.setEndstate("是");
         	a.setEndtime(new Date());
         	this.update(a);
         }
    	 //更新入住状态
         l.setLiveState(LivingState.CHECKOUT.name());
         l.setLeaveDate(new Date());//设置离开时间
    	 l.setSerialNumber(ca.getSerialNumber());//设置与结账一致的序列号
    	 //每个入住的总额，消费、可用进行更新，此时账户消费项状态是"是"
    	 //int consum=livingDao.queryCheckSingleConsum(l.getId(), true);
    	 int consum=this.incomeDao.countAllConsums(l, true, true);
    	 
    	 l.setStorage(consum);
    	 l.setUsed(consum);
    	 l.setAvailable(0);
    	 this.update(l);
    	 //更新房间状态
    	 Room room =l.getRoom();
    	 room.setLiveStatus(RoomLiveStatus.EMPTY.name());
     	 room.setUseStatus(RoomUseStatus.DIRTY.name());
     	 this.update(room);
    	 if(Hotel.onDuty()){
    		 Hotel.receive(-pay, ChargeOpType.OnConsume, PayMethod.valueOf(ca.getType()));
    	 }
    }
    /**
     * 所有入住账务设置完成结账状态及结账时间
     * ***/
    public void updateCheckOutAccount(Living l)
    {
    	List<TbAccounts> Acs = queryAccountsList(l);
    	for(TbAccounts Ac:Acs)
    	{
    		Ac.setEndstate("是");
    		Ac.setEndtime(new Date());
    		this.update(Ac);
    	}
    }
    /**
     * 入住下所账务
     * **/
    public List<TbAccounts> queryAccountsList(Living l)
    {
    	return livingDao.queryAccountsList(l);
    }
    /**
     * 换房
     * **/
	public String changeRoom(LivingSpecifics ls, LivingSpecifics livingLs,
			Living living, TbAccounts ta, Room cRoom, Room selRoom) {
		roomService.updateRoom(cRoom);
		roomService.updateRoom(selRoom);
		if (ta != null)
			this.insert(ta);
		this.insert(ls);
		this.update(livingLs);
		int iStorage =Services.getIncomeService().countAllStroages(living, false);//总存
		int iUsed=Services.getIncomeService().countAllConsumsUsed(living, true,null);//总消费
		int iPaye =Services.getIncomeService().countPayed(living,true);//已支付的
		int sLast=iStorage-iUsed+iPaye;//余额
		living.setStorage(iStorage);
		living.setUsed(iUsed);
		living.setPayed(iPaye);
		living.setAvailable(sLast);
		this.update(living);
		//InComeUtil.updateLiving(living.getId());
		int price =0;
		if(ta!=null)
		{
			price =-ta.getPrice();
		}
        Services.getOtherBusiService().saveChangeRoomBill(living, cRoom.getName(), price, ls.getRemark());
		return null;

	}

    /**
     * 综合入住
     * ***/
	@Deprecated
    public String txLivingMultiple(Living l,LivingSpecifics spec,LivingCustom lc,Room r,TbAccounts accounts,Booking selectBooking,Member m){
    	try{
    		this.insert(l);
    		this.insert(spec);
    		if(m!=null)
    			this.update(m);
    		if(selectBooking!=null){
    			selectBooking.setStatus(BookingStatus.DONE.name());
    			this.update(selectBooking);
    		}
    		this.insert(lc);
    		roomService.updateRoom(r);
    		this.insert(accounts);
    		if(Hotel.onDuty()){
    			Hotel.receive(l.getStorage(), ChargeOpType.OnConsume, PayMethod.valueOf(spec.getPaymentMethod()));
    		}
    		return "";
    	}catch(Exception e){
    		e.printStackTrace();
    		return e.getMessage();
    	}
    }
    /**
     * 是否已经存在当前入住的客人
     * 以录入的身份证判定
     * **/
    public boolean isExistCurCustom(Living l,String passportNumber){
    	boolean re=false;
    	StringBuffer hql = new StringBuffer();
    	hql.append(" from LivingCustom b where 1=1 ").append(" and b.living.id='").append(l.getId()).append("'");
    	hql.append(" and b.certificateno='").append(passportNumber).append("'");
		List<LivingCustom> lclist = this.find(hql.toString());
		if(lclist.size()==0){
			re=false;
		}else{
			re=true;
		}
    	return re;
    }
    public void deleteCustoms(String [] ids){
    	if(ids==null)
			return ;
		for(int i=0;i<ids.length;i++){
			deleteCustom(ids[i]);
		}
    }
    public void deleteCustom(String id){
    	this.delete(LivingCustom.class, id);
    }
    /**
     * 根据入住查询相关客人
     * ***/
    public List<LivingCustom> queryCustoms(Living l){
    	if(l!=null)
    	{
    		StringBuffer hql = new StringBuffer();
        	hql.append(" from LivingCustom b where 1=1 ").append(" and b.living.id='").append(l.getId()).append("'");
        	
    		List<LivingCustom> lclist = this.find(hql.toString());
    		return lclist;
    	}else{
    		return null;
    	}
    }
    /**查询不包括押金的消费情况记录*/
    public List<TbAccounts> queryAccountsNotDeposit(Living l){
    	if(l!=null)
    	{
    		return this.livingDao.queryAccountsNotDeposit(l);
    	}else{
    		return null;
    	}
    }
    
    /**查询物品借用情况 
     * ***/
    public List<TbLiveGoodsBorrow> queryGoodsBorrow(Living l){
    	if(l!=null){
    	StringBuffer hql=new StringBuffer();
    	hql.append(" from TbLiveGoodsBorrow b where b.living.id='"+l.getId()+"'");
	    List <TbLiveGoodsBorrow> goodsBorrowList=this.find(hql.toString());
	    return goodsBorrowList;
    	}else{
    		return null;
    	}
    }
    /**
     * 是否有加收半天或者一天的房费
     * @return
     */
    public boolean isAdd(Living l){
    	if(l==null){
    		return false;
    	}
    	StringBuffer hql=new StringBuffer();
    	 hql.append(" from TbAccounts b where b.state='"+TbAccounts.STATE_NORMAL+"' and b.living.id='"+l.getId()+"' and b.type='");
    	 hql.append(InComeItemType.JSFF.name());
    	 hql.append("'");
    	   List o=this.find(hql.toString());
    	   if(o!=null&&o.size()>=1){
    		 return true;
    	   }
    	   else{
    		   return false;
    	   }
    }
    
    /**
     * 取消预定
     * **/
    public boolean cancelBooking(Booking b) {
	      if(b==null) {
	    	  return false;
	      }
	      if(!BookingStatus.ONGOING.is(b.getStatus())) {
	    	  return false;
	      }
	      b.setStatus(BookingStatus.CANCELED.name());
	      b.setEndTime(new Date());
	      bookingDao.update(b);
	      return true;
    }

    /**
     * 查询统计房间类型及间数*/
    public List queryRoomTypeStatic(){
		 StringBuffer hql=new StringBuffer();
		   hql.append("select b.type.id,b.type.name,count(*),b.type.price as num from Room b where b.repairStatus!='"+RoomRepairStatus.REPAIR+"'");
		   hql.append(" and b.useStatus!='").append(RoomUseStatus.DIRTY).append("'");
		   hql.append(" and b.liveStatus!='").append(RoomLiveStatus.FILLED).append("'");
		   hql.append(" group by b.type.id, b.type.name,b.type.price");
		   return this.find(hql.toString());  
	 }
    /**
     * 查找当前入住的详细信息
     * **/
    public LivingSpecifics querySpec(Living l)
	  {
		  StringBuffer hql = new StringBuffer();
		  hql.append(" from LivingSpecifics b where b.living.id='");
		  hql.append(l.getId()).append("'");
		  hql.append(" and b.operateType='").append(OperateState.LIVING.name()).append("'");
		  List<LivingSpecifics> list= this.find(hql.toString());
		  if(list!=null&&list.size()==1){
			  return (LivingSpecifics)list.get(0);
		  }
		  else
			  return null;
	  }
    public void updateSelfLiving(Living l, LivingSpecifics spec, LivingCustom lc,Room selectRoom, TbAccounts accounts,Card card)
    {
    		this.insert(l);
    		this.insert(spec);
    		this.insert(lc);
    		this.update(selectRoom);
    		if(accounts!=null)
    		  this.insert(accounts);   
    		if(card!=null)
    			this.update(card);
    }
    
    /**
     * 单个房间的入住
     * */
	public void updateSingleRoomLiving(Living living, LivingSpecifics spec, Room curRoom, TbAccounts accounts,
			Member m, LivingCustom lc, Card card, String bookingId) {
    	this.insert(living);
    	this.insert(spec);
    	if(m!=null)
    	  this.update(m);
    	if(lc!=null)
    		this.insert(lc);
    	Services.getRoomService().updateRoom(curRoom);
    	insert(accounts);
    	//写入值班人收入
    	
    	Hotel.receive(living.getStorage(), ChargeOpType.OnConsume, PayMethod.valueOf(spec.getPaymentMethod()),InComeItemType.YJ.getName()+":"+Utils.toPrice(living.getStorage()));
    	
    	if(card!=null)
    		this.update(card);
    	
    	if (StringUtils.isNotEmpty(bookingId)) {
    		Booking booking = get(Booking.class, bookingId);
    		updateBookingStatus(booking, curRoom.getId());
//    		if (booking != null) {
//    			booking.setStatus(BookingStatus.DONE.name());
//    			booking.setEndTime(new Date());
//    			update(booking);
//    			L.update(booking, "预订入住");
//    		}
    	}
    	Services.getOtherBusiService().saveLivingBill(living,spec.getPaymentMethod());
    	L.log(L.Action.INSERT, "living", living.toSimpleString());
    }
	
	private void updateBookingStatus(Booking booking, String roomId) {
		if (booking == null || StringUtils.isEmpty(roomId))
			return;
		Set<BookingRoom> rooms = booking.getBookingRooms();
		if (rooms == null || rooms.isEmpty()) {
			booking.setStatus(BookingStatus.DONE.name());
			update(booking);
			return;
		}
		boolean all  = true;
		for (BookingRoom bookingRoom : rooms) {
			if (roomId.equals(bookingRoom.getRoom().getId())) {
				bookingRoom.setStatus(BookingStatus.DONE.name());
				update(bookingRoom);
				if (!all)
					break;
			}
			if (all && !BookingStatus.DONE.is(bookingRoom.getStatus()))
				all = false;
		}
		if (all) {
			booking.setStatus(BookingStatus.DONE.name());
			update(booking);
		}
	}
	
    /**
     * 根据会员查询是否有入住
     * */
    public Living getSelfMemberLiving(Member M)
    {
    	return livingDao.getLivingByMember(M);
    }
    /**自助退房
     * */
    public void updateSelfCheckOut(Living l,TbAccounts ac,TbCloseAccounts ca,Memberchargehistrory mch,Card c)
    {
    	if(ac!=null)
    	  this.insert(ac);
    	this.update(l);
    	updateCheckOutAccount(l);
    	if(ca!=null)
    	  this.insert(ca);
    	if(mch!=null)
    	  this.insert(mch);
    	Member m =l.getMember();
    	int b =Services.getMemberService().queryMemberBalance(m);
    	m.setBalance(b);
    	this.update(m);
    	Room room =l.getRoom();
    	room.setLiveStatus(RoomLiveStatus.EMPTY.name());
		room.setUseStatus(RoomUseStatus.DIRTY.name());
    	Services.getRoomService().updateRoom(room);
    	Services.getCustomService().insertCustomWhenCheckOut(l);
    	if(c !=null)
    		this.update(c);
    	//写入日志
    	L.log(L.Action.INSERT, "SELFLIVING");
    }
  /**检测入住时的押金是否用会员卡支付
   * 
   * @param l
   * @return
   */
    public boolean isPayByMemberForDeposit(Living l)
    {
    	StringBuffer hql = new StringBuffer();
		  hql.append(" from LivingSpecifics b where b.living.id='");
		  hql.append(l.getId()).append("'");
		  hql.append(" and b.operateType='").append(OperateState.LIVING.name()).append("'");
		  hql.append(" and b.paymentMethod='").append(PayMethod.MEMBER_CARD.name()).append("'");
		  List<LivingSpecifics> list= this.find(hql.toString());
		  if(list!=null&&list.size()>0){
			  return true;
		  }
		  else
			  return false;
    }
    public List<Living> queryPageHQL(String sCustormName,String sLiveState,
    		                         String sRoomName,String sRoomType,
    		                         String sSex,Date startLivingDate,Date endLivingDate,String oType,
    		                         int start,int length)
    {
    	return livingDao.queryPageHQL(sCustormName, sLiveState, sRoomName, sRoomType, sSex, startLivingDate, endLivingDate,oType, start, length);
    }
    public List<Living> queryLiving(String sCustormName,String sLiveState,
            String sRoomName,String sRoomType,
            String sSex,Date startLivingDate,Date endLivingDate,String oType)
    {
    	return livingDao.queryLivingNotPage(sCustormName, sLiveState, sRoomName, sRoomType, sSex, startLivingDate, endLivingDate,oType);
    }
    
    /**
     * 当前入住
     * */
    public List<Living> listCurrentLivings() {
    	return super.query(Living.class, "liveState in (?, ?)", new Object[] {LivingState.LIVING.name(), LivingState.PARTCHECKOUT.name()}, null);
    }
    
    public List<Living> listCurrentBasicLivings() {
    	return livingDao.listCurrentBasicLivings();
    }
    
    public TbCloseAccounts queryLastCloseAccount(Living l){
    	StringBuffer hql = new StringBuffer();
		  hql.append(" from TbCloseAccounts b where b.living.id='").append(l.getId()).append("'");
		  hql.append(" order by b.time desc");
		  List<TbCloseAccounts> list= this.find(hql.toString());
		  if(list!=null&&list.size()!=0)
			  return list.get(0);
		  else
			  return null;
    }
    public void cancel(Living l)
    {
    	if(!Hotel.onDuty()){
    		UIUtils.alert("抱歉你当前不在值班，不能操作此业务!");
    		return ;
    	}
    	if(!Logic.isCancel(l.getId())){
    		UIUtils.alert("当前不是入住状态不能撤消！");
    		return ;
    	}
    	if(Logic.isExceedMinute(l.getLiveTime(), new Date())){
    		UIUtils.alert("已超过："+Config.getCancelLivingMinutes()+"分钟,不能撤消!");
    		return ;
    	}
    	int comsum =Services.getIncomeService().countAllConsums(l, false, true);
    	if(comsum>0)
    	{
    		UIUtils.alert("已经有消费不能撤消!");
    		return ;
    	}
    	LivingSpecifics cs =this.livingDao.querySpecifices(l.getId(), LivingState.LIVING.name());
    	if(cs==null){
    		UIUtils.alert("没有入住详细信息!");
    		return ;
    	}
    	PayMethod p =PayMethod.valueof(cs.getPaymentMethod());
    	
    	StringBuffer msg = new StringBuffer();
    	msg.append("你好！").append(l.getCustormName()).append("\n");
    	
    	int storage =Services.getIncomeService().countAllStroages(l, false);
    	msg.append("退款金额:").append(Utils.toPrice(storage));
    	if(UIUtils.confirm(msg.toString())){
	    	l.setLiveState(LivingState.CANCEL.name());
	    	l.setStorage(0);
	    	l.setAvailable(0);
	    	l.setUsed(0);
	    	Room room =l.getRoom();
	    	room.setLiveStatus(RoomLiveStatus.EMPTY.name());
     		room.setUseStatus(RoomUseStatus.DIRTY.name());
     		this.update(room);
	    	if(storage!=0){
	    	   TbAccounts ac = new TbAccounts();
	    	   ac.setLiving(l);
	    	   ac.setCounts(1);
	    	   ac.setPrice(-storage);
	    	   ac.setName("");
	    	   ac.setType(InComeItemType.CX.name());
	    	   ac.setEndstate("是");
	    	   ac.setOptime(new Date());
			   ac.setPrice2(storage);
			   ac.setOpUser(Hotel.getCurrentUser().getName());
			   ac.setOpdate(DateUtil.currentDateToString(DateUtil.DEFAULT_DATE_FORMAT));
			   ac.setRemark(DateUtil.currentDateToString(DateUtil.DEFAULT_DATE_FORMAT)+"退还:"+Utils.toPrice(storage));
			   this.insert(ac);
	    	}
	    	this.update(l);
	    	Services.getOtherBusiService().saveCancelBill(l, p, storage, "退还:"+Utils.toPrice(storage));
	    	if(storage!=0){
	            Hotel.receive(-storage, ChargeOpType.OnConsume, p,LivingState.CANCEL.getDisplayName()+":"+Utils.toPrice(storage));
	    	}
    	}
    }
    public List<Living> queryTeamLiving(String serialNumber,String livingId)
    {
    	return livingDao.queryTeamLiving(serialNumber,livingId);
    }
    public void updateLiving(Living l,LivingCustom lc,LivingSpecifics cs){
    	this.update(l);
    	if(cs!=null){
    		insert(cs);
    	}
    	if(lc.getId()==null){
    		this.insert(lc);
    	}else
    		this.update(lc);
    }
    public LivingCustom queryLivingCustom(Living l,String passportNumber){
    	StringBuffer hql = new StringBuffer();
    	hql.append(" from LivingCustom b where 1=1 ").append(" and b.living.id='").append(l.getId()).append("'");
    	hql.append(" and b.certificateno='").append(passportNumber).append("'");
		List<LivingCustom> lclist = this.find(hql.toString());
		if(lclist!=null&&lclist.size()!=0)
			  return lclist.get(0);
		  else
			  return null;
    }
    public List<Living> queryTeamOtherLiving(String serialNumber,String nowLivingId){
    	StringBuffer hql = new StringBuffer();
    	hql.append(" from Living b where 1=1 ").append(" and b.id!='").append(nowLivingId).append("'");
    	hql.append(" and b.serialNumber='").append(serialNumber).append("'");
		List<Living> list = this.find(hql.toString());
		return list;
    }
    public List<LivingCustom> queryOtherCustom(String livingId,String cusId){
    	StringBuffer hql = new StringBuffer();
    	hql.append(" from LivingCustom b where 1=1 ").append(" and b.living.id='").append(livingId).append("'");
    	hql.append(" and b.id='").append(cusId).append("'");
		List<LivingCustom> lclist = this.find(hql.toString());
		return lclist;
    }
    public void updateTeamLeader(String livingId){
    	Living l =get(Living.class, livingId);
    	l.setMaster(true);
    	this.update(l);
    	List<Living> other =queryTeamOtherLiving(l.getSerialNumber(),l.getId());
    	if(other!=null){
    		for(Living o:other){
    			o.setMaster(false);
    			this.update(o);
    		}
    	}
    }
    public void updateHostCustorm(String livingId,String cusId){
    	Living l =get(Living.class, livingId);
    	LivingCustom c =get(LivingCustom.class,cusId);
    	c.setIshost("是");
    	update(c);
    	l.setCustormName(c.getName());
    	l.setPassportNumber(c.getCertificateno());
    	l.setPassportType(c.getCertificatetype());
    	l.setPhone(c.getPhone());
    	l.setSex(c.getSex());
    	List<LivingCustom> other =queryOtherCustom(livingId,cusId);
    	if(other!=null){
    		for(LivingCustom o:other){
    			o.setIshost("否");
    			update(o);
    		}
    	}
    }
    public void run(Runnable r) {
    	r.run();
    }

}
